﻿using System;
using System.Collections.Generic;
using System.Security.Permissions;

using Moe.ECamel.Common.Contracts;
using Moe.ECamel.Common.Entities;
using Moe.ECamel.Common.Security;
using Moe.ECamel.Server.BL;

namespace Moe.ECamel.Server.Services
{
	/// <summary>
	/// Service Interface for Customers services.
	/// </summary>
	public class CustomerService : ECamelService, ICustomerService
	{
		public CustomerService()
			: base()
		{
		}
		public CustomerService(ECamelService caller)
			: base(caller)
		{
		}

		#region ICustomerService Members

		/// <summary>
		/// Gets a list of all the customers in the specified library.
		/// </summary>
		/// <param name="libraryId">Library Id to look for.</param>
		/// <returns>List of customers in specified library.</returns>
		[PrincipalPermission(SecurityAction.Demand, Role = Operations.CustomerView)]
		public List<Customer> GetCustomersByLibrary(int libraryId)
		{
			// Execute operation via service BL:
			using (var bl = new CustomerBL(GetReadOnlyDataContext()))
			{
				return bl.GetCustomersByLibrary(libraryId);
			}
		}
		/// <summary>
		/// Get Customer details by customer Id.
		/// </summary>
		/// <param name="customerId">Customer Id</param>
		/// <returns>Customer details.</returns>
		[PrincipalPermission(SecurityAction.Demand, Role = Operations.CustomerView)]
		public Customer GetCustomerById(int customerId)
		{
			using (var bl = new CustomerBL(GetReadOnlyDataContext()))
			{
				return bl.GetCustomerById(customerId);
			}
		}
		public Customer GetCustomerByUserId(int userId)
		{
			using (var bl = new CustomerBL(GetReadOnlyDataContext()))
			{
				return bl.GetCustomerByUserId(userId);
			}
		}
		/// <summary>
		/// Creates a new customer.
		/// </summary>
		/// <param name="customer">Customer details.</param>
		/// <returns>If successful - null, otherwise validation error.</returns>
		[PrincipalPermission(SecurityAction.Demand, Role = Operations.CustomerAdd)]
		public ECamelError CreateCustomer(Customer customer)
		{
			return CreateCustomers(new Customer[] {customer});
		}
		[PrincipalPermission(SecurityAction.Demand, Role = Operations.CustomerAdd)]
		public ECamelError CreateCustomers(IEnumerable<Customer> customers)
		{
			// Set shortcut to data connection:
			ECamelDataContext dataContext = GetReadWriteDataContext();

			// Create customer:
			using (var bl = new CustomerBL(dataContext))
			{
				foreach (var customer in customers)
				{
					// Set customer role:
					customer.User.UserRoles.Add(new UserRoles { User = customer.User, RoleId = Roles.Customer });
					// Create user:
					ECamelError error;
					using (var userService = new UserService(this))
					{
						error = userService.CreateUser(customer.User);
						if (error != null)
							return error;
					}
					error = bl.CreateCustomer(customer);
					if (error != null)
						return error;
				}
			}

			return SubmitChanges(null);
		}
		/// <summary>
		/// Updates a customer.
		/// </summary>
		/// <param name="customer">Customer details.</param>
		/// <returns>If successful - null, otherwise validation error.</returns>
		[PrincipalPermission(SecurityAction.Demand, Role = Operations.CustomerEdit)]
		public ECamelError UpdateCustomer(Customer customer)
		{
			ECamelError error;

			// Update user:
			using (var userService = new UserService(this))
			{
				error = userService.UpdateUser(customer.User);
				if (error != null)
					return error;
			}
			// Update customer:
			using (var bl = new CustomerBL(GetReadWriteDataContext()))
			{
				error = bl.UpdateCustomer(customer);
			}

			return SubmitChanges(error);
		}

		#endregion
	}
}